package com.cm.projectx.service.impl;


import cn.afterturn.easypoi.excel.entity.ExportParams;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cm.projectx.common.PageInfo;
import com.cm.projectx.common.entity.UserContext;
import com.cm.projectx.entity.PriceTask;
import com.cm.projectx.entity.dto.ExcelPriceTaskDto;
import com.cm.projectx.job.entity.JobParamEntity;
import com.cm.projectx.job.service.ScheduleService;
import com.cm.projectx.job.utils.JobParamConvert;
import com.cm.projectx.mapper.PriceTaskMapper;
import com.cm.projectx.response.Result;
import com.cm.projectx.service.IPriceTaskService;
import com.cm.projectx.service.IProcessService;
import com.cm.projectx.service.IProductPriceReportDetailService;
import com.cm.projectx.util.ExcelUtils;
import com.cm.projectx.util.SimplePage;
import com.cm.projectx.vo.PriceSearchVo;
import com.cm.projectx.vo.ProductMonitorRelation;
import com.cm.projectx.vo.QueryTaskListVo;
import com.cm.projectx.vo.TaskVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.util.*;

@Service
@Slf4j
public class PriceTaskServiceImpl extends ServiceImpl<PriceTaskMapper, PriceTask> implements IPriceTaskService {
    @Autowired
    private PriceTaskMapper priceTaskMapper;

    @Autowired
    private ScheduleService scheduleService;

    @Autowired
    private IProcessService processService;

    @Autowired
    private IProductPriceReportDetailService productPriceReportDetailService;

    @Override
    public double getLastTaskProductPrice(String processId, String productId, String monitorId) {
        return 0;
    }


    @Override
    public Result createAndDispatchTask(TaskVo taskVo) {
        Result result = new Result();
        try {
            PriceTask task;

            // 检查任务名称是否重复（排除已废除的状态2）
            if (isTaskNameDuplicate(taskVo.getTaskName(), taskVo.getTaskCode())) {
                result.setCode(-1);
                result.setMsg("任务重名");
                return result;
            }

            // 保存任务信息
            boolean isNewTask = StringUtils.isBlank(taskVo.getTaskCode());
            task = saveOrUpdateTask(taskVo, isNewTask);

            if (task == null) {
                result.setCode(-1);
                result.setMsg("任务保存失败");
                return result;
            }

            // 判断是否需要定义定时任务
            if (!"单次".equals(taskVo.getScheduleType())) {
                // 周期性任务 - 创建定时任务
                createScheduleTask(task);
            } else {
                // 单次任务 - 发起流程
                createSingleTaskProcess(taskVo, task);
            }

            result.setCode(0);
            result.setMsg("任务下发成功");

        } catch (Exception e) {
            log.error("任务下发异常", e);
            result.setCode(-1);
            result.setMsg("任务下发失败: " + e.getMessage());
            // 抛出异常触发事务回滚
            throw new RuntimeException("任务下发失败", e);
        }
        return result;
    }

    @Override
    public PriceTask saveOrUpdateTask(TaskVo taskVo, boolean isNewTask) {
        if (isNewTask) {
            // 新增任务
            String taskCode = UUID.randomUUID().toString().replaceAll("-", "");
            taskVo.setTaskCode(taskCode);
            taskVo.setStatus(1); // 已下发状态
            this.addTask(taskVo);
            return this.getOne(Wrappers.<PriceTask>lambdaQuery().eq(PriceTask::getTaskCode, taskCode));
        } else {
            // 更新任务
            taskVo.setStatus(1); // 已下发状态
            this.updateTask(taskVo);
            PriceTask task = this.getOne(Wrappers.<PriceTask>lambdaQuery().eq(PriceTask::getTaskCode, taskVo.getTaskCode()));
            if (task == null) {
                throw new RuntimeException("任务不存在");
            }
            return task;
        }
    }

    @Override
    public PageInfo<PriceTask> getTaskList(QueryTaskListVo taskListVo) {
        LambdaQueryWrapper<PriceTask> taskLambdaQueryWrapper = buildTaskQueryWrapper(taskListVo, true);
        //构建分页
        IPage<PriceTask> page = new SimplePage<>(taskListVo);
        page = priceTaskMapper.selectPage(page,taskLambdaQueryWrapper);
      //此逻辑对应三期任务列表返回一个字段判断报价时间是多个还是一个
        List<PriceTask> records = page.getRecords();
        records.forEach(record -> {
            PriceSearchVo searchVo = new PriceSearchVo();
            searchVo.setTaskId(String.valueOf(record.getId()));
            Result dateListV3 = productPriceReportDetailService.getDateListV3(searchVo);
            // 获取dateList并判断长度
            List<String> dateList = (List<String>) dateListV3.getData().get("dateList");
            // 如果dateList长度>1，设置为false 如果dateList长度<=1，设置为true
            record.setIsOnlyOne(dateList != null && dateList.size() <= 1);
        });
        return SimplePage.toPageResult(page, PriceTask.class);
    }

    @Override
    public void exportExcel(QueryTaskListVo taskListVo, HttpServletResponse response) throws IOException {
        LambdaQueryWrapper<PriceTask> taskLambdaQueryWrapper = buildTaskQueryWrapper(taskListVo, true);
        // 构建分页
        IPage<PriceTask> page = new SimplePage<>(taskListVo);
        page = priceTaskMapper.selectPage(page, taskLambdaQueryWrapper);
        PageInfo<ExcelPriceTaskDto> pageResult = SimplePage.toPageResult(page, ExcelPriceTaskDto.class);
        List<ExcelPriceTaskDto> data = pageResult.getData();


        ExportParams exportParams = new ExportParams();
        exportParams.setSheetName("任务数据");
        ExcelUtils.exportExcel(response,"任务列表", data, ExcelPriceTaskDto.class, exportParams);
    }


    @Override
    public void addTask(TaskVo taskVo) {
        //获取用户所属组织
        String dataScope = UserContext.getUserDataScope();
        String userName = UserContext.getCurrentUser().getUserName();
        PriceTask priceTask = new PriceTask();
        //任务级别
        priceTask.setTaskLevel(taskVo.getTaskLevel());
        //用户县区
        priceTask.setArea(dataScope);
        //用户名
        priceTask.setUserName(userName);
        //任务编码
        priceTask.setTaskCode(taskVo.getTaskCode());
        //任务名称
        priceTask.setTaskName(taskVo.getTaskName());
        //任务类型
        priceTask.setTaskType(taskVo.getTaskType());
        //周参数
        priceTask.setWeekDay(taskVo.getWeekDay());
        //月对应参数
        priceTask.setDay(taskVo.getDay());
        //旬对应参数
        priceTask.setTenDay(taskVo.getTenDay());
        //自定义cron
        priceTask.setCustomizeCron(taskVo.getCustomizeCron());
        //自定义对应提前天数（1，2，3，4，5）
        priceTask.setAdvanceDays(taskVo.getAdvanceDays());
        //定时任务开启时间
        priceTask.setScheduleTaskStartTime(taskVo.getScheduleTaskStartTime());
        //定时任务结束时间
        priceTask.setScheduleTaskEndTime(taskVo.getScheduleTaskEndTime());
        //报价开始日期
        priceTask.setStartTime(taskVo.getStartTime());
        //报价结束日期
        priceTask.setEndTime(taskVo.getEndTime());
        //任务发起时常(周期任务时取)
        priceTask.setTaskTime(taskVo.getTaskTime());
        //定时周期类型  单次、周报、旬报、月报
        priceTask.setScheduleType(taskVo.getScheduleType());
        //存储了任务的子表信息， 包含商品和各监测点的选择关系
        priceTask.setProductMonitorRelations(JSON.toJSONString(taskVo.getProductMonitorRelations()));
        //价格类型（采集指标多选，存储为json）
        priceTask.setPriceType(JSON.toJSONString(taskVo.getPriceType()));
        //模板code
        priceTask.setDkTemplateTypesCode(taskVo.getDkTemplateTypesCode());
        //任务描述
        priceTask.setTaskRemark(taskVo.getTaskRemark());

        priceTask.setStatus(taskVo.getStatus());
        priceTask.setCreateTime(new Date());
        priceTask.setUpdateTime(new Date());
        priceTask.setCreator(taskVo.getCreator());
        priceTaskMapper.insert(priceTask);
    }
    @Override
    public void updateTask(TaskVo taskVo) {
        //获取用户所属组织
        String dataScope = UserContext.getUserDataScope();
        String userName = UserContext.getCurrentUser().getUserName();
        PriceTask priceTask = new PriceTask();
        //任务id
        priceTask.setId(taskVo.getId());
        //任务级别
        priceTask.setTaskLevel(taskVo.getTaskLevel());
        //用户名
        priceTask.setUserName(userName);
        //用户县区
        priceTask.setArea(dataScope);
        //任务编码
        priceTask.setTaskCode(taskVo.getTaskCode());
        //任务名称
        priceTask.setTaskName(taskVo.getTaskName());
        //任务类型
        priceTask.setTaskType(taskVo.getTaskType());
        //周参数
        priceTask.setWeekDay(taskVo.getWeekDay());
        //月对应参数
        priceTask.setDay(taskVo.getDay());
        //旬对应参数
        priceTask.setTenDay(taskVo.getTenDay());
        //自定义cron
        priceTask.setCustomizeCron(taskVo.getCustomizeCron());
        //自定义对应提前天数（1，2，3，4，5）
        priceTask.setAdvanceDays(taskVo.getAdvanceDays());
        //定时任务开启时间
        priceTask.setScheduleTaskStartTime(taskVo.getScheduleTaskStartTime());
        //定时任务结束时间
        priceTask.setScheduleTaskEndTime(taskVo.getScheduleTaskEndTime());
        //报价开始日期
        priceTask.setStartTime(taskVo.getStartTime());
        //报价结束日期
        priceTask.setEndTime(taskVo.getEndTime());
        //任务发起时常(周期任务时取)
        priceTask.setTaskTime(taskVo.getTaskTime());
        //定时周期类型  单次、周报、旬报、月报
        priceTask.setScheduleType(taskVo.getScheduleType());
        //存储了任务的子表信息， 包含商品和各监测点的选择关系
        priceTask.setProductMonitorRelations(JSON.toJSONString(taskVo.getProductMonitorRelations()));
        //价格类型（采集指标多选，存储为json）
        priceTask.setPriceType(JSON.toJSONString(taskVo.getPriceType()));
        //模板code
        priceTask.setDkTemplateTypesCode(taskVo.getDkTemplateTypesCode());
        priceTask.setStatus(taskVo.getStatus());
        priceTask.setCreateTime(new Date());
        priceTask.setUpdateTime(new Date());
        priceTask.setCreator(taskVo.getCreator());
        priceTaskMapper.updateById(priceTask);
    }
    // ============ 私有方法 ============

    private boolean isTaskNameDuplicate(String taskName, String excludeTaskCode) {
        LambdaQueryWrapper<PriceTask> queryWrapper = Wrappers.<PriceTask>lambdaQuery()
                .eq(PriceTask::getTaskName, taskName)
                .ne(PriceTask::getStatus, "2"); // 排除已废除的任务

        if (StringUtils.isNotBlank(excludeTaskCode)) {
            queryWrapper.ne(PriceTask::getTaskCode, excludeTaskCode);
        }

        return this.count(queryWrapper) > 0;
    }
    private void createScheduleTask(PriceTask task) {
        JobParamEntity jobParam = JobParamConvert.convertByTaskScheduleType(task);
        scheduleService.addSchedule(
                task.getId(),
                jobParam.getJobName(),
                jobParam.getJobGroup(),
                jobParam.getJobClassName(),
                jobParam.getTriggerName(),
                jobParam.getTriggerGroup(),
                jobParam.getCronExpression(),
                jobParam.getScheduleTaskStartTime(),
                jobParam.getScheduleTaskEndTime()
        );
    }

    private void createSingleTaskProcess(TaskVo taskVo, PriceTask task) {
        List<ProductMonitorRelation> productMonitorRelations = taskVo.getProductMonitorRelations();
        processService.startAllProcessOfTask(productMonitorRelations, task);
    }
    private LambdaQueryWrapper<PriceTask> buildTaskQueryWrapper(QueryTaskListVo taskListVo, boolean addDataScope) {
        LambdaQueryWrapper<PriceTask> queryWrapper = Wrappers.lambdaQuery();
        // 添加数据权限条件（可选）
        if (addDataScope) {
            String dataScope = UserContext.getUserDataScope();
            if (!"市人员".equals(dataScope) && StringUtils.isNotBlank(dataScope)) {
                queryWrapper.like(PriceTask::getArea, dataScope);
            }
        }
        // 添加任务名称条件
        if (StringUtils.isNotBlank(taskListVo.getTaskName())) {
            queryWrapper.like(PriceTask::getTaskName, taskListVo.getTaskName());
        }
        // 添加任务类型条件
        if (StringUtils.isNotBlank(taskListVo.getTaskType())) {
            queryWrapper.eq(PriceTask::getTaskType, taskListVo.getTaskType());
        }
        // 添加状态条件
        if (StringUtils.isNotBlank(taskListVo.getStatus())) {
            queryWrapper.eq(PriceTask::getStatus, taskListVo.getStatus());
        }
        //时间筛选
        // 添加时间区间条件（根据createTime查询）
        if (taskListVo.getStartTime() != null && taskListVo.getEndTime() != null) {
            // 开始时间和结束时间都不为空，查询区间
            queryWrapper.between(PriceTask::getCreateTime, taskListVo.getStartTime(), taskListVo.getEndTime());
        } else if (taskListVo.getStartTime() != null) {
            // 只有开始时间，查询大于等于开始时间
            queryWrapper.ge(PriceTask::getCreateTime, taskListVo.getStartTime());
        } else if (taskListVo.getEndTime() != null) {
            // 只有结束时间，查询小于等于结束时间
            queryWrapper.le(PriceTask::getCreateTime, taskListVo.getEndTime());
        }
        //排除模板类型的数据
        //queryWrapper.ne(PriceTask::getStatus,"3");
        queryWrapper.orderByDesc(PriceTask::getUpdateTime);
        return queryWrapper;
    }
}
